﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ServeNHL.Helpers;
using System.Data;

namespace ServeNHL.Models
{
    public class UserViewModel
    {
        public USER user { get; set; }
        public USER_CONTACT contact {get; set;}
        public FAMILY family { get; set; }


        //SEARCH FOR USER (by specific fields) - 3/3/2016 Steve

        // list of family members 
        public List<UserViewModel> getfamily(int? familyid)
        {

           
            var familyMembers = new List<UserViewModel>();
            using (var dbconn = new fclick_dbEntities())
            {

                /*       var query = dbconn.FAMILies.Join(dbconn.USERs, f => f.FAMILY_ID, u => u.FAMILY_ID, (f, u) => new { f, u }).Where(u => u.u.FAMILY_ID == familyid).
                            Select(uvm => new UserViewModel

                            {
                                user = uvm.u,
                                family = uvm.f,
                                  //contact = uvm.
                              }
                            );
                       familyMembers = query.ToList();

                       var contQuery = from u in dbconn.USERs
                                       join uc in dbconn.USER_CONTACT on u.USER_ID equals uc.USER_ID
                                       where u.FAMILY_ID == familyid
                                       select new UserViewModel()
                                       {
                                           contact = uc,
                                       };*/

                //joins all  elements of user view model returns list of view models
                var query = from f in dbconn.FAMILies
                            join u in dbconn.USERs on f.FAMILY_ID equals u.FAMILY_ID
                            join uc in dbconn.USER_CONTACT on u.USER_ID equals uc.USER_ID
                            join user in dbconn.USERs on uc.USER_ID equals user.USER_ID
                            where u.FAMILY_ID == familyid && u.STATUS == "Active"
                              select new UserViewModel()
                              {
                                  family = f,
                                  user =   u,
                                  contact = uc,
                              };




               familyMembers = query.ToList();
                             

            }
            return familyMembers;
        }
        public UserViewModel getUser (string id)
        {
            UserViewModel user = new UserViewModel();

            
            using (var db = new fclick_dbEntities())
            {
                int convertID = Convert.ToInt32(id);
                var q= db.USERs.Where(u => u.USER_ID == convertID).FirstOrDefault();
                user.user = q;

              
                var con = db.USER_CONTACT.Where(c => c.USER_ID == convertID);
                user.contact = con.FirstOrDefault();

                //family
            } 
                

            return user;
        }

        public UserViewModel joinUserFamily (int? id)
        {
            var user = new UserViewModel();
            using(var db = new fclick_dbEntities())
            {
                var query = (from u in db.USERs
                             join f in db. FAMILies on u.FAMILY_ID equals f.FAMILY_ID
                            where u.USER_ID == id
                            select u).FirstOrDefault();

                user.user = query;
                return user;

            }


        }

        /// <summary>
        /// Resets pw 
        /// </summary>
        /// <param name="userid">The user who's pw needs to change</param>
        /// <param name="pw">new Password</param>
        /// <param name="confirmpw">confirm password</param>
        public void resetpw (string username, string pw, string confirmpw)
        {
            USER user = new USER();
            if(pw == confirmpw) {
                using (var db = new fclick_dbEntities())
                {
                    var q = db.USERs.Where(u => u.USERNAME == username);
                    user = q.FirstOrDefault();

                    user.PASSWORD = Helpers.UserHelper.getPasswordSaltHash(pw);

                    db.USERs.Add(user);
                    db.SaveChanges();
                }
             }
        }// end of public void resetpw (string username, string pw, string confirmpw)

        //send reset password email
        //get auto generated pw,  set temp password, send to email,
          public void sendReset(string username)
        {

            StringBuilder sb = new StringBuilder();

            //get autogenerated pw
            string randomPW = Helpers.UserHelper.createTempPassword(); //get autogenerated pw
            
            sb.AppendLine(String.Format("Your Serve NHL password has been reset."));
            sb.AppendLine(Environment.NewLine);
            sb.AppendLine(String.Format("Your temporary password is: " + randomPW));
            string msg = sb.ToString();
            string subject = "Serve NHL Reset Password";
            var user = new UserViewModel();
            user.user = getUserObject(username);

            string passwordHashed = Helpers.UserHelper.getPasswordSaltHash(randomPW);

            //insert new pw into db
            using(var dbconn = new fclick_dbEntities())
            {
               UserViewModel current_user = new UserViewModel();
               current_user.user = dbconn.USERs.First(u => u.USER_ID == user.user.USER_ID);
               current_user.user.PASSWORD = passwordHashed;
               dbconn.SaveChanges();
            }
            

            //send email
            var email = new Email();
            email.sendEmail(username, subject, msg);



        }//end of sendReset()


        /// <summary>
        /// Checks if a given username is already used in the user's table.
        /// </summary>
        /// <param name="userName">Username to check</param>
        /// <returns>False if the username is already in use.</returns>
        public Boolean isAvailableUsername(string userName)
        {
            Boolean isValid = false;

            using (var dbconn = new fclick_dbEntities())
            {
                var count = dbconn.USERs.Count(u => u.USERNAME == userName);
                if(count == 0)
                {
                    isValid = true;
                }
                else
                {
                    isValid = false;
                }
            }
            return isValid;
        } // public Boolean isAvailableUsername(string usrname)

        public List<UserViewModel> findUsers(string name)

        {
            List<UserViewModel> users = new List<UserViewModel>();
            var temp = new UserViewModel();
            string fname = "";
            string lname = "";
            string[] nameArray; 

            if (name.Contains(","))
            {
                nameArray = name.Split(new char[',']);
                fname = nameArray[1];
                lname = nameArray[0];
            }
            else if (name.Contains(" "))
            {
                nameArray = name.Split(new char[' ']);
                fname = nameArray[0];
                lname = nameArray[1];
            }
            else
            {
                fname = name;
                lname = name;
            }
           
            using (var dbconn = new fclick_dbEntities())
            {

                
                    var query = dbconn.USER_CONTACT.Join(dbconn.USERs, uc => uc.USER_ID, uc => uc.USER_ID, (uc, u) => new { uc, u })
                        .Where(uc => uc.uc.FIRST_NAME.Contains(fname) || uc.uc.LAST_NAME.Contains(lname))
                        .Select(vm => new UserViewModel
                        {
                            user = vm.u,
                            contact = vm.uc,


                        });
                    
                    users = query.ToList();
               

               
            }
           
            return users;
        }           // end of public List<UserViewModel> findUsers(string name)

        public USER getUserObject(string userName)
        {
            using (var dbconn = new fclick_dbEntities())
            {
                var query = (from u in dbconn.USERs
                             where u.USERNAME == userName
                             select u).FirstOrDefault();
                return query;
            }
        }

        /// <summary>
        /// Given a user object, sets status to Inactive.
        /// </summary>
        /// <param name="user">User to disable.</param>
        /// <returns>Status message.</returns>
        public string RemoveUser(USER user)
        {
            string message = "Could not locate user.";

            using (var dbconn = new fclick_dbEntities())
            {
                var query = (from u in dbconn.USERs
                             where u.USER_ID == user.USER_ID
                             select u).FirstOrDefault();

                query.STATUS = "Inactive";
                message = "Disabled User";
                dbconn.SaveChanges();
               
            }

            // Remove from family table, uncomment if needed, but we can keep them in the family if their account is active.
            // FamilyViewModel FVM = new FamilyViewModel();
            // FVM.RemoveFromFamily(user);

            // Remove the user from all signed up events
            eventViewModel EVM = new eventViewModel();
            EVM.RemoveFromAllEvents(user);


            return message;
        }

        /// <summary>
        /// Given a user ID number, this will update any of the fields given to it. Default values are null if you don't send it every field, so only send what you need.
        /// </summary>
        /// <param name="id">User ID to edit</param>
        /// <param name="username">Username to update.</param>
        /// <param name="phone">Phone number to update.</param>
        /// <param name="carrier">Phone carrier to update.</param>
        /// <param name="firstName">First Name to update.</param>
        /// <param name="lastName">Last Name to update.</param>
        /// <param name="password">Password to update. Will be hashed.</param>
        public void UpdateUserInfo(int id, string username = null, string phone = null, string carrier = null, string firstName = null, string lastName = null, string password = null)
        {
            using (var dbconn = new fclick_dbEntities())
            {

                // Updates the data in the USERs table
                var query = (from u in dbconn.USERs
                             where u.USER_ID == id
                             select u).FirstOrDefault();

                USER tUser = query;
                if (!String.IsNullOrEmpty(username))
                {
                    tUser.USERNAME = username;
                }

                if (!String.IsNullOrEmpty(password))
                {
                    tUser.PASSWORD = Helpers.UserHelper.getPasswordSaltHash(password);
                }

                // Updates the data in the USER_CONTACT table
                var contactQuery = (from u in dbconn.USER_CONTACT
                                    where u.USER_ID == id
                                    select u).FirstOrDefault();

                USER_CONTACT tContact = contactQuery;
                if (!String.IsNullOrEmpty(phone))
                {
                    tContact.PHONE = phone;
                }

                if (!String.IsNullOrEmpty(carrier))
                {
                    tContact.CARRIER = carrier;
                }
                if (!String.IsNullOrEmpty(username))
                {
                    tContact.EMAIL = username;
                }

                if (!String.IsNullOrEmpty(firstName))
                {
                    tContact.FIRST_NAME = firstName;
                }

                if (!String.IsNullOrEmpty(lastName))
                {
                    tContact.LAST_NAME = lastName;
                }

                dbconn.SaveChanges();
            }
        } // End of public void UpdateUserInfo(int id, string username = null, string phone = null, string carrier = null, string firstName = null, string lastName = null, string password = null)
    }
}
